import ArrayUtil from './ArrayUtil'

export default {
    /**
     * 查找包含字段值的数据
     * @param {*} tree 
     * @param {*} key 
     * @param {*} value 
     * @param {*} config 
     */
    findOne(tree, key, value, config = {
        "id": "id",
        "name": null,
        "pid": "pid",
        "children": "children",
        "pid_name": null,
        "pid_code": null,
        "pid_level": null,
    }) {
        let listHandle = function (tree, key, value, config, listHandle) {
            for (let i = 0; i < tree.length; i++) {
                const item = tree[i];
                if (item[key] == value) {
                    return item
                }
                if (item[config["children"]]) {
                    let children = listHandle(item[config["children"]], key, value, config, listHandle);
                    if (children != null) {
                        return children
                    }
                }
            }
            return null
        }
        return listHandle(tree, key, value, config, listHandle)
    },
    /**
     * 通过self查找树结构数据
     * @param {*} tree 
     * @param {*} self 
     * @param {*} config 
     */
    findTreeBySelf(tree, self, config = {
        "id": "id",
        "name": null,
        "pid": "pid",
        "children": "children",
        "pid_name": null,
        "pid_code": null,
        "pid_level": null,
    }) {
        listHandle = function (tree, self, config, listHandle) {
            for (let i = 0; i < tree.length; i++) {
                const item = tree[i]
                if (item[config["id"]] == self) {
                    return item
                }
                if (is_array(item[config["children"]])) {
                    let children = listHandle(item[config["children"]], self, config, listHandle)
                    if (!is_null(children)) {
                        return children
                    }
                }
            }
            return null
        };
        return listHandle(tree, self, config, listHandle)
    },
    /**
     * 获取树结构单个列数据
     * @param {*} tree 
     * @param {*} column 
     * @param {*} config 
     */
    treeToColumn(tree, column, config = {
        "id": "id",
        "name": null,
        "pid": "pid",
        "children": "children",
        "pid_name": null,
        "pid_code": null,
        "pid_level": null,
    }) {
        let list = this.treeToList(tree, config)
        let columns = []
        for (let i = 0; i < list.length; i++) {
            const item = list[i]
            columns.push(item[column])
        }
        return columns
    },
    /**
     * 查找包含字段值的数据
     * @param {*} tree 
     * @param {*} key 
     * @param {*} value 
     * @param {*} config 
     */
    findAll(tree, key, value, config = {
        "id": "id",
        "name": null,
        "pid": "pid",
        "children": "children",
        "pid_name": null,
        "pid_code": null,
        "pid_level": null,
    }) {
        let list = [];
        let listHandle = function (tree, key, value, config, listHandle) {
            for (let i = 0; i < tree.length; i++) {
                const item = tree[i]
                if (item[key] == value) {
                    list.push(item)
                }
                if (is_array(item[config["children"]])) {
                    listHandle(item[config["children"]], key, value, config, listHandle)
                }
            }
        };
        listHandle(tree, key, value, config, listHandle)
        return list
    },
    /**
     * 数组转树结构
     * @param {*} list 
     * @param {*} config 
     * @returns 
     */
    listToTree(list, config = {
        "id": "id",
        "name": null,
        "pid": "pid",
        "children": "children",
        "pid_name": null,
        "pid_code": null,
        "pid_level": null,
    }) {
        let app = this
        let treeHandle = function (parent, list, treeHandle) {
            let topTree = []
            let childrenList = []
            for (let i = 0; i < list.length; i++) {
                let childrenItem = list[i]
                let parentCount = 0
                for (let j = 0; j < list.length; j++) {
                    let parentItem = list[j]
                    if (parentItem[config["id"]] != childrenItem[config["id"]]) {
                        if (parentItem[config["id"]] == childrenItem[config["pid"]]) {
                            ++parentCount
                            childrenList.push(childrenItem)
                        } else if (config["pid_code"] != null
                            && childrenItem[config["pid_code"]].split(',').includes(String(parentItem[config["id"]]))) {
                            ++parentCount
                            childrenList.push(childrenItem)
                        }
                    }
                }
                if (parentCount == 0) {
                    if (parent == null) {
                        topTree.push(childrenItem)
                    } else if (parent[config["id"]] == childrenItem[config["pid"]]) {
                        topTree.push(childrenItem)
                    } else if (config["pid_code"] != null
                        && childrenItem[config["pid_code"]].split(',').includes(String(parent[config["id"]]))) {
                        topTree.push(childrenItem)
                    }
                }
            }
            for (let i = 0; i < topTree.length; i++) {
                let topTreeItem = topTree[i]
                childrenList = ArrayUtil.distinct(childrenList, config["id"])
                topTreeItem['children'] = treeHandle(topTreeItem, childrenList, treeHandle)
                let tempChildren = ArrayUtil.diff(childrenList, app.treeToList(topTreeItem['children']), config["id"])
                for (let j = 0; j < tempChildren.length; j++) {
                    let tempChildrenItem = tempChildren[j]
                    if (topTreeItem[config["id"]] == tempChildrenItem[config["pid"]]) {
                        topTreeItem['children'].push(tempChildrenItem)
                    } else if (config["pid_code"] != null
                        && tempChildrenItem[config["pid_code"]].split(',').includes(String(topTreeItem[config["id"]]))) {
                        topTreeItem['children'].push(tempChildrenItem)
                    }
                }
            }
        }
        return treeHandle(null, list, treeHandle)
    },
    /**
     * 树结构转数组
     * @param {*} tree 
     * @param {*} config 
     * @returns 
     */
    treeToList(tree, config = {
        "id": "id",
        "name": null,
        "pid": "pid",
        "children": "children",
        "unset_children": true,
        "pid_name": null,
        "pid_code": null,
        "pid_level": null,
    }) {
        let listHandle = function (tree, config, listHandle) {
            if (!Array.isArray(tree)) {
                return []
            }
            let list = []
            for (let i = 0; i < tree.length; i++) {
                const item = tree[i]
                let children = null
                if (item[config["children"]]) {
                    children = item[config["children"]]
                    if (config["unset_children"]) {
                        delete item[config["children"]]
                    }
                }
                list.push(item)
                if (Array.isArray(children)) {
                    list = [...list, ...listHandle(children, config, listHandle)]
                }
            }
            return list
        }
        return listHandle(tree, config, listHandle)
    },
    /**
     * 递归遍历数据
     * @param {*} paramOrTree 
     * @param {*} mainNext 
     * @param {*} node 
     * @returns 
     */
    recursion(paramOrTree, mainNext, node = { "level": 0, "top": true, "parent": null, "parents": [] }) {
        return mainNext(paramOrTree, function (paramOrTree, parent) {
            return this.recursion(paramOrTree, mainNext, {
                "parent": parent,
                "parents": [...node["parents"], parent],
                "level": node["level"] + 1,
                "top": false,
            })
        }.bind(this), node)
    },
    /**
     * 递归遍历数据
     * @param {*} tree 
     * @param {*} func 
     * @param {*} config 
     */
    recursionEach(tree, func, config = {
        "id": "id",
        "name": null,
        "pid": "pid",
        "children": "children",
        "pid_name": null,
        "pid_code": null,
        "pid_level": null,
    }) {
        let treeHandle = function (tree, treeHandle, node = { "level": 0, "top": true, "parent": null, "parents": [] }) {
            for (let i = 0; i < tree.length; i++) {
                let item = tree[i]
                func(item, node)
                if (item[config['children']]) {
                    treeHandle(item[config['children']], treeHandle, {
                        "parent": item,
                        "parents": [...node["parents"], item],
                        "level": node["level"] + 1,
                        "top": false,
                    })
                }
            }
        }
        treeHandle(tree, treeHandle)
    },
}